/*
 * © 2024 huayunliufeng保留所有权利, 依据MIT许可证发布。
 * 请勿更改或删除版权声明或此文件头。
 * 此代码是免费软件, 您可以重新分发和/或修改它。
 * 开源是希望它有用, 但不对代码做任何保证。
 * 如有疑问请联系: huayunliufeng@163.com
 */

package io.github.huayunliufeng.common.utils;

import org.apache.commons.lang3.StringUtils;

/**
 * 常用方法。
 *
 * @author huayu 2024/5/13 16:39
 * @version 0.0.4-4
 * @since 0.0.4-4
 */
public class HylfIpAddressUtil {
    /**
     * 将点分十进制形式(127.0.0.1这种)的ip地址转换为long类型。
     *
     * @param ipv4Str 合法的ipv4地址字符串
     * @return long
     */
    public static long ipv4StrToLong(String ipv4Str) {
        if (!checkIpv4(ipv4Str)) {
            throw new RuntimeException("不是合法的ipv4地址。");
        }
        String[] strings = ipv4Str.split("\\.");
        long ipAddress = 0;
        int b = 24;
        for (String s : strings) {
            ipAddress |= Long.parseLong(s) << b;
            b -= 8;
        }
        return ipAddress;
    }

    /**
     * 将点分十进制形式(127.0.0.1这种)的ip地址转换为byte数组, 其中第一个数字在最高位。
     *
     * @param ipv4Str 合法的ipv4地址字符串
     * @return byte[]
     */
    public static byte[] ipv4StrToByteArray(String ipv4Str) {
        if (!checkIpv4(ipv4Str)) {
            throw new RuntimeException("不是合法的ipv4地址。");
        }
        byte[] bytes = new byte[4];
        String[] strings = ipv4Str.split("\\.");
        for (int i = 0; i < 4; i++) {
            bytes[3 - i] = Byte.parseByte(strings[i]);
        }
        return bytes;
    }

    public static String longIpv4ToStr(long ipv4) {
        if (!checkIpv4(ipv4)) {
            throw new RuntimeException("不是合法的ipv4地址。");
        }
        return (ipv4 >> 24 & 0xff) + "." + ((ipv4 >> 16) & 0xff) + "." + ((ipv4 >> 8) & 0xff) + "." + (ipv4 & 0xff);
    }

    public static byte[] longIpv4ToByteArray(long ipv4) {
        if (!checkIpv4(ipv4)) {
            throw new RuntimeException("不是合法的ipv4地址。");
        }
        byte[] bytes = new byte[4];
        for (int i = 0; i < 4; i++) {
            bytes[3 - i] = (byte) (ipv4 >> (i * 8));
        }
        return bytes;
    }

    public static boolean checkIpv4(long ipv4) {
        return ipv4 >= 0 && ipv4 <= 0xffffffffL;
    }

    public static boolean checkIpv4(String ipStr) {
        if (StringUtils.isEmpty(ipStr)) {
            return false;
        }
        String[] strings = ipStr.split("\\.");
        if (strings.length != 4) {
            return false;
        }
        for (String s : strings) {
            try {
                int i = Integer.parseInt(s);
                if (i < 0 || i > 255) {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
        }
        return true;
    }
}
